#include <iostream>
#include <sstream>
#include <string>
#include <opencv2/opencv.hpp>
#include <X11/Xlib.h>
using namespace std;

void showImage(cv::Mat img){
    if(img.rows>0&&img.cols>0){
        int n=img.channels();
        if(n!=1&&n!=3&&n!=4){//只显示单通道与三通道的图片
            cout<<"only images with one or three or four channel(s) can be displayed!"<<endl;
            return;
        }
        stringstream ss;
        ss<<"img_"<<img.rows<<"x"<<img.cols<<"_"<<img.channels()<<"channels_";
        switch (img.depth())
        {
        case CV_8U:ss<<"8U";break;
        case CV_8S:ss<<"8S";break;
        case CV_16U:ss<<"16U";break;
        case CV_16S:ss<<"16S";break;
        case CV_32S:ss<<"32S";break;
        case CV_32F:ss<<"32F";break;
        case CV_64F:ss<<"64F";break;
        default:ss<<"8U";break;
        }
        string title=ss.str();
        cv::namedWindow(title,cv::WINDOW_NORMAL);
        if(img.type()!=CV_8UC(n)){
            // cv::normalize(img,img,0,255,cv::NORM_MINMAX);
            img.convertTo(img,CV_8UC(n));
        }
        int w=img.cols;
        int h=img.rows;
        //get screen size
        Display *d=XOpenDisplay(NULL);
        Screen *s=DefaultScreenOfDisplay(d);
        float max_width=s->width/2;//以本窗口为最大尺寸
        float max_height=s->height;
        //adjust image size if too large
        if(h>max_height*0.9||w>max_width*0.9){
            float scale_x=(float)w/max_width/0.9;
            float scale_y=(float)h/max_height/0.9;
            float scale=scale_x>scale_y?scale_x:scale_y;
            w=int(float(w)/scale);
            h=int(float(h)/scale);
        }
        cv::resizeWindow(title,w,h);
        cv::imshow(title,img);
        cv::waitKey(0);
        cv::destroyAllWindows();
    }
    else{//图片为空(无行无列)的时候
        cout<<"image is empty!"<<endl;
    }
}

int main(int argc, char**argv) {
    if(argc!=2){
        cout<<"usage:OpenCVViewer image_file"<<endl;
        return 1;
    }
    string fileName=argv[1];
    cv::Mat img=cv::imread(fileName,cv::IMREAD_UNCHANGED);
    showImage(img);
}
